using System;
using System.Web;
using System.Text;
using System.Collections;
using System.IO;
using System.Data;
using PKMCDO;
using SharePoint.ImportExport.Core;
using System.Reflection;
using System.Runtime.InteropServices;
using SharePoint.ImportExport.ExportSPS2001.ExportData;
using SharePoint.ImportExport.ExportSPS2001.ExportDataHandler;
namespace SharePoint.ImportExport.ExportSPS2001.ExportData
{
	/// <summary>
	/// Summary description for Class1.
	/// </summary> 
	/// 
	public class Handler
	{
		#region Private Members
		ADODB.ConnectionClass Conn = null;
		private PKMCDO.KnowledgeWorkspace workSpace;
		private PKMCDO.KnowledgeFolderClass KMFolder;
		private SharePoint.ImportExport.Core.Import import ;
		private bool exportVersions=false;
		private System.Array propertyDefs;
		private SharePoint.ImportExport.ExportSPS2001.ExportDataHandler.ContentClassManager contentClassManager;
		private string workspaceName;
		private string exportDirectoryName;
		private string exportFolderName;
		private SiteType siteType=SiteType.Site;
		private string rootContainerName;
		private string owner;
		private string email;
		private string siteDefinitionName;
		#endregion
		#region Public Members

		public string SiteDefinitionName
		{
			set
			{
				siteDefinitionName=value;
			}
		}
		/// <summary>
		/// This will be the owner of the site
		/// </summary>
		public string Owner
		{
			set
			{
				owner=value;
			}
		}
		public string Email
		{
			set
			{
				email=value;
			}
		}
		/// <summary>
		/// This is the name if the sitecollection root
		/// </summary>
		public string RootContainerName
		{
			set
			{
				rootContainerName=value;
			}
		}

			/// <summary>
			/// This is the the type of site that is being created
			/// </summary>
			public SiteType ImportSiteType
		{
			set
			{
				siteType=value;
			}
		}
		/// <summary>
		/// This is the starting point for the extraction
		/// </summary>
		public string ExportFolderName
		{
			set
			{
				exportFolderName=value;
			}
		}
		/// <summary>
		/// This is the name of the SPS 2001 Workspace
		/// </summary>
		public string WorkspaceName
		{
			set
			{
				workspaceName=value;
			}
		}

		/// <summary>
		/// This is the name of the directory where the data is exported
		/// </summary>
		public string ExportDirectoryName
		{
			set
			{
				exportDirectoryName=value;
			}
		}
		/// <summary>
		/// Will versions be exported
		/// </summary>
		public bool ExportVersions
		{
			set
			{
				exportVersions=value;
			}
		}
		#endregion
		public Handler()
		{
			workSpace=new PKMCDO.KnowledgeWorkspace();
			Logger.Init("sps2001export.log",ErrorLevel.Warning);
			contentClassManager=new ContentClassManager();
		}

		void ProcessUsers(Security usersContainer, PKMCDO.KnowledgeFolderClass folder)
		{
			
			try
			{
				AddUsers(usersContainer,"Administrator",(System.Array)folder.Coordinators) ;
			}
			catch
			{
			}
			try
			{
			AddUsers(usersContainer,"Editor",(System.Array)folder.Authors) ;
			}
			catch
			{
			}
			try
			{
				AddUsers(usersContainer,"Reader",(System.Array)folder.Readers) ;
			}
			catch
			{
			}

		}
		void AddUsers(Security usersContainer, string role, System.Array userArray)
		{
			try
			{
				foreach(string userName in userArray)
				{
					User user=new User();
					if(userName== "\\Everyone")
						user.Account="Everyone";
					else
						user.Account=userName;
					user.Role=role;
				
					usersContainer.Users.Add(user);
					Logger.Log(ErrorLevel.Progress,"Adding user: "+userName+" to role "+role);
				}
			}
			catch(Exception Ex)
			{
				Logger.Log(ErrorLevel.Error,"Exception when adding users. Error: "+Ex.Message);
			}

		}
		private string GetValue(ADODB.Field field, string defaultValue)
		{
			string returnValue=defaultValue;
			try
			{
				returnValue=field.Value.ToString();
			}
			catch(Exception Ex)
			{
				Logger.Log(ErrorLevel.Error,"Could not retrieve the property. Error: "+Ex.Message);
			}
			return returnValue;
		}
		private string GetValue(PKMCDO._Recordset rs, string fieldName, string defaultValue, bool logErrors)
		{
			string returnValue=defaultValue;
			try
			{
				returnValue=rs.Fields[fieldName].Value.ToString();
			}
			catch(Exception Ex)
			{
				if(logErrors)
					Logger.Log(ErrorLevel.Error,"Could not retrieve the property. Error: "+Ex.Message);
			}
			return returnValue;
		}
		private string GetValue(PKMCDO.Field field, string defaultValue)
		{
			string returnValue=defaultValue;
			try
			{
				returnValue=field.Value.ToString();
			}
			catch(Exception Ex)
			{
				Logger.Log(ErrorLevel.Error,"Could not retrieve the property. Error: "+Ex.Message);
			}
			return returnValue;
		}
		public bool Process()
		{
			Conn = new ADODB.ConnectionClass();
			try
			{
				Directory.CreateDirectory(exportDirectoryName);
				Directory.SetCurrentDirectory(exportDirectoryName);
				Conn.ConnectionString = "provider=msdaipp.dso";
				Conn.CommandTimeout = 0;
				Conn.Open(workspaceName,null,null,0);

				workSpace.DataSource.Open(workspaceName,Conn, PKMCDO.ConnectModeEnum.adModeReadWrite,PKMCDO.RecordCreateOptionsEnum.adFailIfNotExists,PKMCDO.RecordOpenOptionsEnum.adOpenSource,"","");
				CreateListtemplates();
				//Create a new instance of the Import class
				import = new Import();
				import.Settings.Locale="1033"; //US english
        
				RootContainer rootContainer= new RootContainer();
				rootContainer.Type=siteType; //SiteType.Site=WSS site, SiteType.Area=Portal area
				rootContainer.Name=rootContainerName;

				//This class is the actual site that will be created
				SharePoint.ImportExport.Core.Container container= new Container();
				rootContainer.Containers.Add(container);
				import.RootContainers.Add(rootContainer);

				container.Name=workSpace.DisplayName;
				if(owner==null)
					container.Owner=GetValue(workSpace.Fields["urn:schemas-microsoft-com:publishing:owner"],"");
				else
					container.Owner=owner;

				container.Description=GetValue(workSpace.Fields["urn:schemas-microsoft-com:office:office#Description"],"");
				if(email!=null)
          container.Contact=email;
				container.Type=SiteType.Site;
				container.Template=siteDefinitionName;

				PKMCDO.KnowledgeFolderClass rootFolder=new PKMCDO.KnowledgeFolderClass();				
				rootFolder.DataSource.Open(workspaceName,Conn, PKMCDO.ConnectModeEnum.adModeReadWrite,PKMCDO.RecordCreateOptionsEnum.adFailIfNotExists,PKMCDO.RecordOpenOptionsEnum.adOpenSource,"","");
				ProcessUsers(container.Security,rootFolder);
				System.Runtime.InteropServices.Marshal.ReleaseComObject(rootFolder);
			




				ExportContent(container,exportFolderName);
				Conn.Close();
				Logger.Log(ErrorLevel.Progress,"All done");
				
			}
			catch(COMException ComEx)
			{
				Logger.Log(ErrorLevel.Error,ComEx.Message);
			}
			catch(Exception Ex)
			{
				Logger.Log(ErrorLevel.Error,Ex.Message);
			}
			finally
			{
				if(Conn.State==1)
					Conn.Close();
				System.Runtime.InteropServices.Marshal.ReleaseComObject(workSpace);
				
			}
		
			return true;
		}


		/// <summary>
		/// This creates the listtemplates
		/// </summary>
		public bool CreateListtemplates()
		{
			/* Create a new instance of the ListTemplates class*/
			SharePoint.ImportExport.Core.ListTemplatesList listtemplates= new ListTemplatesList();
			object oTemp;
			propertyDefs=(System.Array)workSpace.PropertyDefs;

			System.Array contentClasses=(System.Array)workSpace.ContentClasses;
			foreach(string contentClassName in contentClasses)
			{
				object ocontentClassName=contentClassName;
				object o=workSpace.GetObject(ref ocontentClassName);
				PKMCDO.KnowledgeContentClassClass contentClass=(PKMCDO.KnowledgeContentClassClass)Marshal.CreateWrapperOfType(o,typeof(PKMCDO.KnowledgeContentClassClass));
				Logger.Log(ErrorLevel.Progress,"Processing content class: "+contentClass.Name);
				System.Array publishingPropertyorderList=(Array)contentClass.get_Property("urn:schemas-microsoft-com:publishing:propertyorder");
				/* Create a new instance of the ListTemplate class and add it to the ListTemplate collection */
				ListTemplate listTemplate= new ListTemplate();
				PropertiesAndTemplate pt=new PropertiesAndTemplate(publishingPropertyorderList.GetLength(0));
				pt.lt=listTemplate;
				

				listTemplate.NameAttribute=contentClass.Title;
				listTemplate.Name=contentClass.Title;
				listTemplate.Title=contentClass.Title;
				listTemplate.EnableVersioning=false;
				if(contentClass.Name.EndsWith("newsitem"))
					listTemplate.BaseType="Announcements";
				else if(contentClass.Name.EndsWith("weblink"))
					listTemplate.BaseType="Links";
				else
				{
					listTemplate.BaseType="DocumentLibrary";
					
					if(exportVersions)
						listTemplate.EnableVersioning=true;
				}
				listTemplate.Description=contentClass.Description;;
				listTemplate.EnableAttachments=false;
				listTemplate.EnableVersioning=false;
				listtemplates.ListTemplates.Add(listTemplate);

				int i=0;
				PropertyDefinition propDef=new PropertyDefinition();
				propDef.Name="ContentClass";
				propDef.Type=FieldType.Text;
				propDef.SPSFieldName="DAV:contentclass";
				pt.properties.SetValue(propDef,i);
				i++;

				propDef=new PropertyDefinition();
				propDef.Name="Created";
				propDef.Type=FieldType.DateTime;
				propDef.SPSFieldName="DAV:creationdate";
				propDef.AddToSharePoint=true;
				pt.properties.SetValue(propDef,i);
				i++;

				propDef=new PropertyDefinition();
				propDef.Name="Modified";
				propDef.Type=FieldType.DateTime;
				propDef.SPSFieldName="DAV:getlastmodified";
				propDef.AddToSharePoint=true;
				pt.properties.SetValue(propDef,i);
				i++;

				propDef=new PropertyDefinition();
				propDef.Name="Author";
				propDef.Type=FieldType.User;
				propDef.SPSFieldName="urn:schemas-microsoft-com:publishing:owner";
				propDef.AddToSharePoint=true;
				pt.properties.SetValue(propDef,i);
				i++;

				propDef=new PropertyDefinition();
				propDef.Name="Editor";
				propDef.Type=FieldType.User;
				propDef.SPSFieldName="urn:schemas-microsoft-com:publishing:publishedby";
				propDef.AddToSharePoint=true;
				pt.properties.SetValue(propDef,i);
				i++;

				propDef=new PropertyDefinition();
				propDef.Name="HRef";
				propDef.Type=FieldType.URL;
				propDef.SPSFieldName="DAV:href";
				pt.properties.SetValue(propDef,i);
				i++;
				
				foreach(object prop in publishingPropertyorderList)
				{
					foreach(string propertyDefName in propertyDefs)
					{
						if(prop.ToString()==propertyDefName)
						{
							object opropertyDefName=propertyDefName;
							oTemp=workSpace.GetObject(ref opropertyDefName);
							PKMCDO.KnowledgePropertyDefClass spspropDef=(PKMCDO.KnowledgePropertyDefClass)Marshal.CreateWrapperOfType(oTemp,typeof(PKMCDO.KnowledgePropertyDefClass));
							string s=spspropDef.DisplayName;
							SharePoint.ImportExport.Core.Field field=new SharePoint.ImportExport.Core.Field();
							field.Name=spspropDef.Title;
							field.Richtext=false;
							
							if(propertyDefName.EndsWith("Author"))
								continue;
							if(propertyDefName.EndsWith("Title"))
								continue;
							field.AddToDefaultView=true;
							switch(spspropDef.Type)
							{
								case "float":
								case "number":
								case "r4":
								case "r8":
									field.Extendedtype=FieldType.Number;
									break	;
								case "int":
								case "long":
								case "ui1":
								case "ui2":
								case "ui4":
								case "ui8":
								case "i1":
								case "i2":
								case "i4":
								case "i8":
									field.Extendedtype=FieldType.Integer;
									break	;
								case "string":
									field.Extendedtype=FieldType.Text;
									break	;
								case "boolean":
									field.Extendedtype=FieldType.Boolean;
									break	;
								case "date":
								case "dateTime":
								case "dateTime.tz":
								case "time":
								case "time.tz":
									field.Extendedtype=FieldType.DateTime;
									break	;
								default:
									field.Extendedtype=FieldType.Text;
									break	;


							}
							
							field.Displayname=spspropDef.Title;
							propDef=new PropertyDefinition();
							if(prop.ToString()=="urn:schemas-microsoft-com:publishing:ShortcutTarget")
								field.Extendedtype=FieldType.URL;
							propDef.Name=field.Name;
							propDef.Type=field.Extendedtype;
							propDef.SPSFieldName=propertyDefName;
							propDef.AddToSharePoint=true;
							pt.properties.SetValue(propDef,i);

							i++;
							if(field.Name=="Title")
								continue;
							if(field.Name=="Author")
								continue;

							listTemplate.Fields.Add(field);

						}
					}
				}

				contentClassManager.AddContentClass(contentClassName,pt);
				//Add a new custom field called MyField and add it fo the Fields collection

			}
			listtemplates.Serialize(exportDirectoryName+"\\ListTemplates.xml");

			
	
			return true;
		}
//		private bool ExportDataContent(PKMCDO.KnowledgeFolder folder,DataContainer parentDataContainer, string folderURL, string contentClassName,Profile parentProfile)
//		{
//			
//			string currentDir=Directory.GetCurrentDirectory();
//			bool returnValue=true;
//			string URL=""; 
//			try
//			{
//				SharePoint.ImportExport.Core.List list=null;
//				DataContainer dataContainer=null;
//				Profile profile=null;
//
//				Directory.CreateDirectory(folder.DisplayName);
//				Logger.Log(ErrorLevel.Progress,"Processing folder: "+folder.DisplayName+" for content of type "+contentClassName);
//				Directory.SetCurrentDirectory(folder.DisplayName);
//				URL = folder.get_Property("RESOURCE_ABSOLUTEPARSENAME").ToString();
//				URL="/"+workSpace.DisplayName+URL.Substring(workspaceName.Length);
//				URL=HttpUtility.UrlDecode(URL);
//				
//				string query = "SELECT * from scope('shallow traversal of \"" + URL+ "\"') WHERE \"DAV:isfolder\" = FALSE AND \"DAV:contentclass\"='"+contentClassName +"' ORDER BY \"DAV:contentclass\" ";
//				
//				//query = "SELECT \"DAV:href\", \"DAV:displayname\" FROM SCOPE('SHALLOW TRAVERSAL OF \"/Migration/Documents\"') ";
//				
//				ADODB.RecordsetClass rs= new ADODB.RecordsetClass();
//				rs.Open(query, Conn, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic, -1);
//
//
//				PropertiesAndTemplate pt=(PropertiesAndTemplate)contentClassManager.GetContentClass(contentClassName);
//
//				
//				if(contentClassName=="urn:content-classes:weblink" || contentClassName=="urn:content-classes:newsitem")
//				{
//					dataContainer=parentDataContainer;
//					profile=parentProfile;
//				}
//				else
//				{
//					dataContainer=new DataContainer();
//					dataContainer.Name=folder.DisplayName;
//					dataContainer.Type=DataContainerType.Folder;
//					dataContainer.Template=pt.lt.Name;
//					dataContainer.BaseTemplate=pt.lt.BaseType;
//
//					parentDataContainer.DataContainers.Add(dataContainer);
//
//				}
//				if(!folder.RolesAreInherited)
//				{
//					AddUsers(dataContainer.Security,"Administrator",(System.Array)folder.Coordinators) ;
//					AddUsers(dataContainer.Security,"Editor",(System.Array)folder.Authors) ;
//					AddUsers(dataContainer.Security,"Reader",(System.Array)folder.Readers) ;
//
//				}
//				
//				if(!rs.EOF)
//				{
//					if(contentClassName=="urn:content-classes:weblink" || contentClassName=="urn:content-classes:newsitem")
//					{
//					}
//					else
//					{
//
//						list=new List();
//						profile=new Profile();
//						list.Profiles.Add(profile);
//						profile.Name=pt.lt.Name;
//						dataContainer.RelativeitemXML=Directory.GetCurrentDirectory().Substring(exportDirectoryName.Length)+ "\\items.xml";
//
//					}
//				}
////				if(contentClassName!="urn:content-classes:weblink" && contentClassName!="urn:content-classes:newsitem")
////					ExportListData(rs,pt,profile,contentClassName);
////				else
////					ExportData(rs,pt,profile,contentClassName);
//
//
//
//				if(folder.HasSubs)
//				{
//					query = "SELECT \"DAV:href\" from scope('shallow traversal of \"" + URL+ "\"') WHERE \"DAV:isfolder\" = TRUE ";
//				
//					//query = "SELECT \"DAV:href\", \"DAV:displayname\" FROM SCOPE('SHALLOW TRAVERSAL OF \"/Migration/Documents\"') ";
//				
//					ADODB.RecordsetClass rsSubs= new ADODB.RecordsetClass();
//					rsSubs.Open(query, Conn, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic, -1);
//					while(!rsSubs.EOF)
//					{
//						//Logger.Log(ErrorLevel.Progress,rsSubs.Fields["DAV:href"].Value.ToString());
//						
//						string hRef=HttpUtility.UrlDecode(rsSubs.Fields["DAV:href"].Value.ToString());
//						PKMCDO.KnowledgeFolder subFolder= new PKMCDO.KnowledgeFolder();
//						subFolder.DataSource.Open(hRef,Conn, PKMCDO.ConnectModeEnum.adModeReadWrite,PKMCDO.RecordCreateOptionsEnum.adFailIfNotExists, PKMCDO.RecordOpenOptionsEnum.adOpenSource, "", ""); 
//
//						ExportDataContent(subFolder,dataContainer,folderURL+"/"+subFolder.DisplayName,contentClassName,profile);
//						rsSubs.MoveNext();
//					}
//				}
//				rs.Close();
//				try
//				{
////					if(list!=null)
////						list.Serialize("items.xml");
//				}
//				catch(SPExportException ex)
//				{
//					Console.WriteLine("Exception occurred: "+ex.Message);
//				}
//
//			}
//			catch(COMException ComEx)
//			{
//				Logger.Log(ErrorLevel.Error,"COMException when processing folder: "+folder.DisplayName+". Error: "+ComEx.Message);
//			}
//			catch(Exception Ex)
//			{
//				Logger.Log(ErrorLevel.Error,"Exception when processing folder: "+folder.DisplayName+". Error: "+Ex.Message);
//			}
//			finally
//			{
//				Directory.SetCurrentDirectory(currentDir);
//			}
//
//			return returnValue;
//		}
		private void ExportLibraryData(PKMCDO.KnowledgeFolderClass folder,PropertiesAndTemplate pt, string contentClassName, Profile profile, DataContainer dataContainer)
		{
			try
			{
				ADODB.RecordsetClass rs= new ADODB.RecordsetClass();
				string sSearch = folder.get_Property("RESOURCE_ABSOLUTEPARSENAME").ToString();
				sSearch=HttpUtility.UrlDecode("/"+workSpace.DisplayName+sSearch.Substring(workspaceName.Length));
				string query;
				query= "SELECT * from scope('shallow traversal of \"" + sSearch + "\"') WHERE \"DAV:isfolder\" = false AND \"DAV:contentclass\"='"+contentClassName +"' ORDER BY \"DAV:contentclass\" ";
				//query = "SELECT \"DAV:href\", \"DAV:displayname\" FROM SCOPE('SHALLOW TRAVERSAL OF \"/Migration/Documents\"') ";
				rs.Open(query, Conn, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic, -1);

				while(!rs.EOF)
				{

					string thisContentClass=rs.Fields["DAV:contentclass"].Value.ToString();

					Item item= new Item();
					Object vEmpty = Missing.Value;

					profile.Items.Add(item);
					string hRef=HttpUtility.UrlDecode( rs.Fields["DAV:href"].Value.ToString());
					item.Displayname=rs.Fields["DAV:displayname"].Value.ToString();
					item.Filename=item.Displayname;
                    PKMCDO.KnowledgeDocumentClass doc = new PKMCDO.KnowledgeDocumentClass();
                    PKMCDO.KnowledgeDocumentClass historyDoc = new PKMCDO.KnowledgeDocumentClass();
					doc.DataSource.Open(hRef,Conn, PKMCDO.ConnectModeEnum.adModeRead,PKMCDO.RecordCreateOptionsEnum.adFailIfNotExists, PKMCDO.RecordOpenOptionsEnum.adOpenSource, "", ""); 

					PKMCDO.KnowledgeVersionClass versionDoc=new KnowledgeVersionClass();
					PKMCDO._Recordset versions =versionDoc.VersionHistory(hRef,0);
					while(!versions.EOF)
					{
						Item versionItem=new Item();
						versionItem.Displayname= item.Displayname;
						versionItem.Filename=Guid.NewGuid().ToString()+".bin";
						historyDoc.DataSource.Open(HttpUtility.UrlDecode(versions.Fields["DAV:href"].Value.ToString()),Conn, PKMCDO.ConnectModeEnum.adModeRead,PKMCDO.RecordCreateOptionsEnum.adFailIfNotExists, PKMCDO.RecordOpenOptionsEnum.adOpenSource, "", ""); 
						PKMCDO._Stream histstream=historyDoc.OpenStream(vEmpty,PKMCDO.EnumKnowledge_StreamOpenSourceType.pkmOpenStreamUnspecified,"",PKMCDO.ConnectModeEnum.adModeRead,"",					"");
						histstream.SaveToFile(versionItem.Filename,PKMCDO.SaveOptionsEnum.adSaveCreateOverWrite);
						histstream.Close();
						versionItem.Comment=GetValue(versions,"urn:schemas-microsoft-com:publishing:Comment","",false);
						versionItem.Owner=GetValue(versions,"urn:schemas-microsoft-com:publishing:User","",false);
						versionItem.Version=GetValue(versions,"urn:schemas-microsoft-com:publishing:FriendlyVersionID","",false);
						foreach(PropertyDefinition propDef in pt.properties)
						{
							try
							{
								if(propDef.AddToSharePoint)
								{
									Itemfield itemField= new Itemfield();

									itemField.Name=propDef.Name;
									itemField.Type=propDef.Type;
									itemField.Value=GetValue(versions,propDef.SPSFieldName,"",false);
									item.Fields.Add(itemField);
								}
							}
							catch
							{
							}
						}

						item.Versions.Add(versionItem);
						versions.MoveNext();
					}
					
			
					PKMCDO._Stream stream=doc.OpenStream(vEmpty,PKMCDO.EnumKnowledge_StreamOpenSourceType.pkmOpenStreamUnspecified,"",PKMCDO.ConnectModeEnum.adModeRead,"",					"");
					stream.SaveToFile(item.Filename,PKMCDO.SaveOptionsEnum.adSaveCreateOverWrite);
					stream.Close();
				
					foreach(PropertyDefinition propDef in pt.properties)
					{
						try
						{
							if(propDef.AddToSharePoint)
							{
								Itemfield itemField= new Itemfield();

								itemField.Name=propDef.Name;
								itemField.Type=propDef.Type;
								itemField.Value=GetValue(rs.Fields[propDef.SPSFieldName],"");
								if(itemField.Value.Trim().Length>0)
									item.Fields.Add(itemField);
							}
						}
						catch
						{
						}


					}

					rs.MoveNext();
				}
				try
				{
					if(folder.HasSubs)
					{
						string curDir=Directory.GetCurrentDirectory();
						PKMCDO._Recordset rsFolders=folder.Subfolders;
						while(!rsFolders.EOF)
						{
							Directory.SetCurrentDirectory(curDir);
							string hRef=rsFolders.Fields["DAV:href"].Value.ToString();
							PKMCDO.KnowledgeFolderClass subFolder= new PKMCDO.KnowledgeFolderClass();
							subFolder.DataSource.Open(hRef,Conn, PKMCDO.ConnectModeEnum.adModeReadWrite,PKMCDO.RecordCreateOptionsEnum.adFailIfNotExists, PKMCDO.RecordOpenOptionsEnum.adOpenSource, "", ""); 
							Directory.CreateDirectory(subFolder.DisplayName);
							Directory.SetCurrentDirectory(subFolder.DisplayName);
							SharePoint.ImportExport.Core.List list=null;
							Profile thisProfile=null;
							list=new List();
							thisProfile=new Profile();
							list.Profiles.Add(thisProfile);
							thisProfile.Name=pt.lt.Name;
							DataContainer subContainer=new DataContainer();
							subContainer.Name=subFolder.DisplayName;
							subContainer.Type=DataContainerType.Folder;
							subContainer.Template=dataContainer.Template;
							subContainer.BaseTemplate=dataContainer.BaseTemplate;
							subContainer.RelativeitemXML=dataContainer.RelativeitemXML.Replace("\\items.xml","\\"+subFolder.DisplayName+"\\items.xml");

							ExportLibraryData(subFolder,pt,contentClassName,thisProfile, subContainer);
							if(subFolder.HasSubs)
								dataContainer.DataContainers.Add(subContainer);
							else
							{
								 if(thisProfile.Items.Count>0)
									 dataContainer.DataContainers.Add(subContainer);
							}

							Directory.SetCurrentDirectory(curDir);
							Directory.SetCurrentDirectory(subFolder.DisplayName);

							if(thisProfile.Items.Count>0)
								list.Serialize("items.xml");
							rsFolders.MoveNext();
						}
					}
				}
				catch
				{
				}

			}
			catch
			{	
			}
		}
		private void ExportListData(PKMCDO.KnowledgeFolderClass folder,PropertiesAndTemplate pt, string contentClassName, Profile profile)
		{
			ADODB.RecordsetClass rs= new ADODB.RecordsetClass();
			string sSearch = folder.get_Property("RESOURCE_ABSOLUTEPARSENAME").ToString();
			sSearch=HttpUtility.UrlDecode( "/"+workSpace.DisplayName+sSearch.Substring(workspaceName.Length));
			string query;
			query= "SELECT * from scope('shallow traversal of \"" + sSearch + "\"') WHERE \"DAV:isfolder\" = false AND \"DAV:contentclass\"='"+contentClassName +"' ORDER BY \"DAV:contentclass\" ";
			//query = "SELECT \"DAV:href\", \"DAV:displayname\" FROM SCOPE('SHALLOW TRAVERSAL OF \"/Migration/Documents\"') ";
			rs.Open(query, Conn, ADODB.CursorTypeEnum.adOpenKeyset, ADODB.LockTypeEnum.adLockOptimistic, -1);

			while(!rs.EOF)
			{

				string thisContentClass=rs.Fields["DAV:contentclass"].Value.ToString();

				Item item= new Item();
				Object vEmpty = Missing.Value;

				profile.Items.Add(item);
				string hRef=HttpUtility.UrlDecode( rs.Fields["DAV:href"].Value.ToString());
				
				foreach(PropertyDefinition propDef in pt.properties)
				{
					try
					{
						if(propDef.AddToSharePoint)
						{
							Itemfield itemField= new Itemfield();
							itemField.Value=GetValue(rs.Fields[propDef.SPSFieldName],"");

							if(propDef.Type==FieldType.URL)
							{
								itemField.Name="URL";
								itemField.Value=itemField.Value+", "+GetValue(rs.Fields["urn:schemas-microsoft-com:office:office#Title"],"");
							}

							else
								itemField.Name=propDef.Name;

							itemField.Type=propDef.Type;
							if(itemField.Value.Trim().Length>0)
								item.Fields.Add(itemField);
						}
					}
					catch
					{
					}


				}

				rs.MoveNext();
			}
			try
			{
				if(folder.HasSubs)
				{
					PKMCDO._Recordset rsFolders=folder.Subfolders;
					while(!rsFolders.EOF)
				
					{
						string hRef=rsFolders.Fields["DAV:href"].Value.ToString();
						PKMCDO.KnowledgeFolderClass subFolder= new PKMCDO.KnowledgeFolderClass();
						subFolder.DataSource.Open(hRef,Conn, PKMCDO.ConnectModeEnum.adModeReadWrite,PKMCDO.RecordCreateOptionsEnum.adFailIfNotExists, PKMCDO.RecordOpenOptionsEnum.adOpenSource, "", ""); 

						ExportListData(subFolder,pt,contentClassName,profile);
						rsFolders.MoveNext();
					}
				}
			}
			catch
			{
			}


		}

//		private void ExportData(ADODB.RecordsetClass rs,PropertiesAndTemplate pt,Profile profile, string contentClassName)
//		{
//			Directory.CreateDirectory("cc_"+pt.lt.Name);
//			Directory.SetCurrentDirectory("cc_"+pt.lt.Name);
//			while(!rs.EOF)
//			{
//
//				string thisContentClass=rs.Fields["DAV:contentclass"].Value.ToString();
//
//				Item item= new Item();
//				Object vEmpty = Missing.Value;
//
//				profile.Items.Add(item);
//				string hRef=HttpUtility.UrlDecode( rs.Fields["DAV:href"].Value.ToString());
//				if(contentClassName!="urn:content-classes:weblink" && contentClassName!="urn:content-classes:newsitem")
//				{
//
//					item.Displayname=rs.Fields["DAV:displayname"].Value.ToString();
//					item.Filename=item.Displayname;
//					PKMCDO.KnowledgeDocumentClass doc=new KnowledgeDocumentClass();
//					PKMCDO.KnowledgeDocumentClass historyDoc=new KnowledgeDocumentClass();
//					doc.DataSource.Open(hRef,Conn, PKMCDO.ConnectModeEnum.adModeRead,PKMCDO.RecordCreateOptionsEnum.adFailIfNotExists, PKMCDO.RecordOpenOptionsEnum.adOpenSource, "", ""); 
//
//					PKMCDO.KnowledgeVersionClass versionDoc=new KnowledgeVersionClass();
//					PKMCDO._Recordset versions =versionDoc.VersionHistory(hRef,0);
//					while(!versions.EOF)
//					{
//						Item versionItem=new Item();
//						versionItem.Displayname= item.Displayname;
//						versionItem.Filename=Guid.NewGuid().ToString()+".bin";
//						historyDoc.DataSource.Open(HttpUtility.UrlDecode(versions.Fields["DAV:href"].Value.ToString()),Conn, PKMCDO.ConnectModeEnum.adModeRead,PKMCDO.RecordCreateOptionsEnum.adFailIfNotExists, PKMCDO.RecordOpenOptionsEnum.adOpenSource, "", ""); 
//						PKMCDO._Stream histstream=historyDoc.OpenStream(vEmpty,PKMCDO.EnumKnowledge_StreamOpenSourceType.pkmOpenStreamUnspecified,"",PKMCDO.ConnectModeEnum.adModeRead,"",					"");
//						histstream.SaveToFile(versionItem.Filename,PKMCDO.SaveOptionsEnum.adSaveCreateOverWrite);
//						histstream.Close();
//						versionItem.Comment=GetValue(versions,"urn:schemas-microsoft-com:publishing:Comment","",false);
//						versionItem.Owner=GetValue(versions,"urn:schemas-microsoft-com:publishing:User","",false);
//						versionItem.Version=GetValue(versions,"urn:schemas-microsoft-com:publishing:FriendlyVersionID","",false);
//						foreach(PropertyDefinition propDef in pt.properties)
//						{
//							try
//							{
//								if(propDef.AddToSharePoint)
//								{
//									Itemfield itemField= new Itemfield();
//
//									itemField.Name=propDef.Name;
//									itemField.Type=propDef.Type;
//									itemField.Value=GetValue(versions,propDef.SPSFieldName,"",false);
//									item.Fields.Add(itemField);
//								}
//							}
//							catch
//							{
//							}
//						}
//
//						item.Versions.Add(versionItem);
//						versions.MoveNext();
//					}
//					
//			
//					PKMCDO._Stream stream=doc.OpenStream(vEmpty,PKMCDO.EnumKnowledge_StreamOpenSourceType.pkmOpenStreamUnspecified,"",PKMCDO.ConnectModeEnum.adModeRead,"",					"");
//					stream.SaveToFile(item.Filename,PKMCDO.SaveOptionsEnum.adSaveCreateOverWrite);
//					stream.Close();
//				}
//				
//				foreach(PropertyDefinition propDef in pt.properties)
//				{
//					try
//					{
//						if(propDef.AddToSharePoint)
//						{
//							Itemfield itemField= new Itemfield();
//
//							itemField.Name=propDef.Name;
//							itemField.Type=propDef.Type;
//							itemField.Value=GetValue(rs.Fields[propDef.SPSFieldName],"");
//							if(itemField.Value.Trim().Length>0)
//								item.Fields.Add(itemField);
//						}
//					}
//					catch
//					{
//					}
//
//
//				}
//
//				rs.MoveNext();
//			}
//
//			Directory.SetCurrentDirectory("..");
//
//
//		}
		public void CleanupEmptyDataContainers(DataContainersCollection dataContainers)
		{
			int i=0;
			if(dataContainers.Count>0)
			{
				System.Collections.ArrayList tobeRemoved=new ArrayList(dataContainers.Count);
				
				for(i=0;i<dataContainers.Count;i++)
				{
					DataContainer dc=dataContainers[i];
					if(dc.DataContainers.Count>0)
						CleanupEmptyDataContainers(dc.DataContainers);
					else
					{
						if(!File.Exists(exportDirectoryName+dc.RelativeitemXML))
						{	
							tobeRemoved.Add(dc.Name);
						}
					}
				}
				foreach(object empty in tobeRemoved)
				{
					if(null!=empty)
					{
						string Name=(string)empty;
						dataContainers.Remove(Name);
					}
				}

			}
		}

		private bool ExportContent(Container container, string folderURL)
		{
			
			if(folderURL.Length==0)
			{
				folderURL=workSpace.get_Property(PKMCDO.KnowledgePropertyDefs.cdostrURI_DocumentsFolder).ToString();
				if(!folderURL.StartsWith("/"))
					folderURL="/"+folderURL;
			}

			KMFolder= new PKMCDO.KnowledgeFolderClass();
			KMFolder.DataSource.Open(workspaceName+folderURL,null, PKMCDO.ConnectModeEnum.adModeReadWrite,PKMCDO.RecordCreateOptionsEnum.adFailIfNotExists, PKMCDO.RecordOpenOptionsEnum.adOpenSource, "", ""); 
//			Directory.CreateDirectory(KMFolder.DisplayName);
//			Directory.SetCurrentDirectory(KMFolder.DisplayName);
			System.Array contentClasses=(System.Array)workSpace.ContentClasses;

			foreach(string contentClassName in contentClasses)
			{
				string type=contentClassName.Substring(contentClassName.LastIndexOf(":")+1);
				Directory.SetCurrentDirectory(exportDirectoryName);
				Directory.CreateDirectory("cc_"+type);
				Directory.SetCurrentDirectory("cc_"+type);

				DataContainer dataContainer=null;

				PropertiesAndTemplate pt=null;
				dataContainer=new DataContainer();
				if(!KMFolder.RolesAreInherited)
				{
					AddUsers(dataContainer.Security,"Administrator",(Array)KMFolder.Coordinators) ;
					AddUsers(dataContainer.Security,"Author",(Array)KMFolder.Authors) ;
					AddUsers(dataContainer.Security,"Reader",(Array)KMFolder.Readers) ;
				}

				pt=(PropertiesAndTemplate)contentClassManager.GetContentClass(contentClassName);
				SharePoint.ImportExport.Core.List list=null;
				Profile profile=null;
				list=new List();
				profile=new Profile();
				list.Profiles.Add(profile);
				profile.Name=pt.lt.Name;
				dataContainer.Name=pt.lt.Name;;
				dataContainer.Template=pt.lt.Name;
				dataContainer.BaseTemplate=pt.lt.BaseType;
				dataContainer.RelativeitemXML="\\cc_"+type+ "\\items.xml";
				dataContainer.WebPart=true;
				

				if(contentClassName=="urn:content-classes:weblink" || contentClassName=="urn:content-classes:newsitem")
				{
					ExportListData(KMFolder,pt,contentClassName,profile);
					if(profile.Items.Count>0)
					{
						container.DataContainers.Add(dataContainer);
						try
						{
							if(list!=null)
								list.Serialize("items.xml");
						}
						catch(SPExportException ex)
						{
							Console.WriteLine("Exception occurred: "+ex.Message);
						}
					}
				}
				else
				{
					ExportLibraryData(KMFolder,pt,contentClassName,profile,dataContainer);	
					Directory.SetCurrentDirectory(exportDirectoryName);
					Directory.SetCurrentDirectory("cc_"+type);

					container.DataContainers.Add(dataContainer);
					try
					{
						if(list!=null)
							list.Serialize("items.xml");
					}
					catch(SPExportException ex)
					{
						Console.WriteLine("Exception occurred: "+ex.Message);
					}
				}
				Directory.SetCurrentDirectory("..");

			}
			CleanupEmptyDataContainers(container.DataContainers);
			if(!import.Validate())
			{
				Logger.Log(ErrorLevel.Error, "Validation failed, last error: "+import.LastError);
			}
			else
			{
    
				try
				{
					import.Serialize(exportDirectoryName+"\\struct.xml");
				}
				catch(SPExportException ex)
				{
					Console.WriteLine("Exception occurred: "+ex.Message);
				}
			}
			

			

			return true;
		}

	}
}
